﻿#pragma once

#include "../repo/src/include/root/rpc_transport.h"
#include <cstdint>

// 前置声明，依赖knet
typedef struct _ringbuffer_t kringbuffer_t;

namespace kratos {
namespace service {

// 容器网络接口
class BoxNetwork;

/**
 * RPC管道实现类
 * @see rpc::Transport.
 */
class BoxChannel : public rpc::Transport {
  kringbuffer_t* rb_     {nullptr};   ///< 缓冲区, 暂存从网络线程接收到的数据
  BoxNetwork*    network_{nullptr};   ///< 网络实例

  std::string    channel_name_;       ///< 管道名称
  std::string    coro_listener_name_; ///< 协程监听器名称, 名字对应在协程内启动的监听器

  std::uint64_t  user_data_ {0};      ///< 用户数据
  std::uint64_t  channel_id_{0};      ///< 管道ID

  bool           is_close_{false};    ///< 关闭标志

public:
  /**
   * 构造函数
   *
   * \param channel_id 管道ID
   * \param network    网络实例
   * \param name       管道名称
   */
  BoxChannel(
    std::uint64_t      channel_id,
    BoxNetwork*        network,
    const std::string& name
  );
  /**
   * 析构 
   */
  virtual ~BoxChannel();
  /**
   * @see rpc::Transport::send
   */
  virtual int send(const char *data, const int size) override;
  /**
   * @see rpc::Transport::peek
   */
  virtual int peek(char *data, const int size) override;
  /**
   * @see rpc::Transport::recv
   */
  virtual int recv(char *data, const int size) override;
  /**
   * @see rpc::Transport::skip
   */
  virtual int skip(const int size) override;
  /**
   * @see rpc::Transport::size
   */
  virtual int size() override;
  /**
   * @see rpc::Transport::isClose
   */
  virtual bool isClose() override;
  /**
   * @see rpc::Transport::close
   */
  virtual void close() override;
  /**
   * 取得管道ID
   *
   * \return 管道ID
   */
  auto get_id() const noexcept -> std::uint64_t;
  /**
   * 将从对端接收到的数据写入读缓冲区
   *
   * \param data 数据指针
   * \param size 数据长度, 字节
   * \return 实际写入的长度
   */
  auto write_buffer(const char *data, int size) noexcept -> int;
  /**
   * 设置关闭标志为true
   */
  auto set_close_flag() noexcept -> void;
  /**
   * 返回管道名称
   *
   * \return 管道名称
   */
  auto get_channel_name() const noexcept -> const std::string&;
  /**
   * 设置管道名称.
   * 
   * \param name 管道名称.
   * \return 
   */
  auto set_channel_name(const std::string& name) noexcept ->void;
  /**
   * 设置协程监听器名称.
   * 
   * \param name 协程监听器名称.
   * \return 
   */
  auto set_coro_listener_name(const std::string& name) noexcept -> void;
  /**
   * 获取协程监听器名称.
   * 
   * \return 协程监听器名称.
   */
  auto get_coro_listener_name() const noexcept -> const std::string&;
  /**
   * 设置用户数据.
   * 
   * \param user_data 用户数据
   * \return 
   */
  auto set_user_data(std::uint64_t user_data) noexcept -> void;
  /**
   * 获取用户数据.
   * 
   * \return 用户数据
   */
  auto get_user_data() const noexcept -> std::uint64_t;
  /**
   * 获取用户数据.
   * 
   * \return 用户数据
   */
  template <typename T>
  auto cast_user_data() noexcept -> T {
    return reinterpret_cast<T>(user_data_);
  }
};

} // namespace service
} // namespace kratos
